package device

import (
	"fmt"
	"golang.org/x/sys/unix"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)

func check(err error) {
	if err != nil {
		log.Panic(err)
	}
}

func GetCPU() {
	fmt.Println("hello world")
}

// {"mem":{"free":7083768,"total":7956696,"used":607092},"swap":{"free":2097152,"total":2097152},"timestamp":1761117728}
func GetMem() map[string]interface{} {
	fileData, err := os.ReadFile("/proc/meminfo")
	check(err)

	memInfo := make(map[string]int)

	lines := strings.Split(string(fileData), "\n")
	for _, line := range lines {
		if strings.TrimSpace(line) == "" {
			continue
		}
		parts := strings.Fields(line)
		if len(parts) >= 2 {
			key := strings.TrimSuffix(parts[0], ":")
			value := parts[1]
			memInfo[key], err = strconv.Atoi(value)
			check(err)
		}
	}

	// meminfo to `free` cmd
	mem := map[string]interface{}{
		"timestamp": time.Now().Unix(),
		"unit":      "kB",
		"mem": map[string]int{
			"total": memInfo["MemTotal"],
			"used":  memInfo["MemTotal"] - memInfo["MemAvailable"],
			"free":  memInfo["MemFree"],
		},
		"swap": map[string]int{
			"total": memInfo["SwapTotal"],
			"free":  memInfo["SwapFree"],
		},
	}

	return mem
}

// {"disk":{"available":984726868,"free":1038430340,"total":1055762868,"used":17332528},"path":"/","timestamp":1761119241,"unit":"kB"}
func GetDisk(path string) map[string]interface{} {
	var stat unix.Statfs_t
	err := unix.Statfs(path, &stat)
	check(err)

	total := stat.Blocks * uint64(stat.Bsize)
	free := stat.Bfree * uint64(stat.Bsize)
	avail := stat.Bavail * uint64(stat.Bsize)
	used := total - free

	disk := map[string]interface{}{
		"timestamp": time.Now().Unix(),
		"unit":      "kB",
		"path":      path,
		"disk": map[string]uint64{
			"total": total / 1024,
			"used":  used / 1024,
			"avail": avail / 1024,
			"free":  free / 1024,
		},
	}

	return disk
}

func GetUptime() map[string]interface{} {
	fileData, err := os.ReadFile("/proc/uptime")
	if err != nil {
		panic(err)
	}

	var uptime, idle float64
	fmt.Sscanf(string(fileData), "%f %f", &uptime, &idle)

	jdata := map[string]interface{}{
		"timestamp": time.Now().Unix(),
		"unit":      "S",
		"uptime":    uptime,
	}

	return jdata
}

func GetUser() map[string]interface{} {
	username := os.Getenv("USER")
	jdata := map[string]interface{}{
		"user": username,
	}

	return jdata
}
